package cn.shujuhai.common.service.impl;

import cn.shujuhai.common.domain.*;
import cn.shujuhai.common.mapper.SysRoleMapper;
import cn.shujuhai.common.pluging.data.ResultCode;
import cn.shujuhai.common.pluging.data.ResultVo;
import cn.shujuhai.common.service.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author NiuYaHu
 * @description 针对表【sys_role(角色表)】的数据库操作Service实现
 * @createDate 2024-10-17 14:37:55
 */
@Service
@RequiredArgsConstructor
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole>
        implements SysRoleService {
    private final SysUserRoleService sysUserRoleService;
    private final SysRolePermissionService sysRolePermissionService;
    private final SysRoleChannelService sysRoleChannelService;
    private final SysRoleInfoService sysRoleInfoService;
    private final SysRoleMapper sysRoleMapper;


    /**
     * 分页查询系统角色信息
     *
     * @param roleName 角色名（可为null，不为null时进行模糊查询）
     * @param roleCode 角色代码（可为null，不为null时进行模糊查询）
     * @param page     当前页码（从1开始）
     * @param pageSize 每页显示的记录数
     * @return 返回包含分页信息和系统用户列表的ResultVo对象，其中PageInfo<SysUser>包含了分页的详细信息，如总记录数、总页数等
     */
    @Override
    public ResultVo<PageInfo<SysRole>> getSysRolePageInfo(String roleName, String roleCode, Integer page, Integer pageSize) {
        PageHelper.startPage(page, pageSize);
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        if (roleName != null && !roleName.isEmpty()) {
            queryWrapper.like("role_name", roleName);
        }
        if (roleCode != null && !roleCode.isEmpty()) {
            queryWrapper.like("role_code", roleCode);
        }
        List<SysRole> sysRoleList = this.list(queryWrapper.lambda().orderByDesc(SysRole::getRoleId)); //根据角色Id排序
        PageInfo<SysRole> sysUserPageInfo = new PageInfo<>(sysRoleList);
        return ResultVo.success(sysUserPageInfo);
    }

    /**
     * 根据角色ID查询系统角色信息
     *
     * @param roleId 角色id
     * @return 返回对应的系统角色对象（SysRole），如果未找到则返回null
     */
    @Override
    public ResultVo<SysRole> selectById(Integer roleId) {
        SysRole sysRole = this.getById(roleId);
        return ResultVo.success(sysRole);
    }

    /**
     * 根据角色ID删除角色信息
     *
     * @param roleId 角色id
     * @return 删除成功或失败的结果及响应信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo<SysRole> removeId(Integer roleId) {
        List<SysUserRole> sysUserRoles = this.sysUserRoleService.list(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getRoleId, roleId));
        if (!sysUserRoles.isEmpty()) {
            return ResultVo.failure(ResultCode.NO_REMOVE);
        } else {
            this.sysRolePermissionService.remove(new QueryWrapper<SysRolePermission>()
                    .lambda().eq(SysRolePermission::getRoleId, roleId));
            this.sysRoleChannelService.remove(new QueryWrapper<SysRoleChannel>()
                    .lambda().eq(SysRoleChannel::getRoleId, roleId));
            this.sysRoleInfoService.remove(new QueryWrapper<SysRoleInfo>()
                    .lambda().eq(SysRoleInfo::getRoleId, roleId));
            if (this.removeById(roleId)) {
                return ResultVo.success();
            }
            return ResultVo.failure(ResultCode.FAILED);
        }
    }

    /**
     * 启用｜禁用 角色
     *
     * @param roleId 角色id
     * @return 获取修改角色id, 返回更新后的角色
     */
    @Override
    public ResultVo<SysRole> enable(Integer roleId) {
        // 根据角色ID获取角色对象
        SysRole sysRole = this.getById(roleId);
        // 切换状态
        sysRole.setStatus(sysRole.getStatus() == 0 ? 1 : 0);
        // 更新角色状态
        if (this.updateById(sysRole)) {
            return ResultVo.success();
        } else {
            return ResultVo.failure(ResultCode.FAILED);
        }
    }

    /**
     * 角色新增
     *
     * @param sysRole 角色对象
     * @return 新增的角色对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo<?> saveRolePermission(@Validated SysRole sysRole) {
        if (this.save(sysRole)) {
            List<SysRolePermission> permissionsToSave = new ArrayList<>();
            List<SysRoleChannel> channelToSave = new ArrayList<>();
            List<SysRoleInfo> infoToSave = new ArrayList<>();

            // 处理权限
            if (sysRole.getPermissionIds() != null && !sysRole.getPermissionIds().isEmpty()) {
                for (Long permissionId : sysRole.getPermissionIds()) {
                    SysRolePermission sysRolePermission = new SysRolePermission();
                    sysRolePermission.setRoleId(sysRole.getRoleId());
                    sysRolePermission.setPermissionId(permissionId);
                    permissionsToSave.add(sysRolePermission);
                }
                // 保存权限
                if (!this.sysRolePermissionService.saveBatch(permissionsToSave)) {
                    return ResultVo.failure(ResultCode.FAILED);
                }
            }
            // 处理栏目
            if (sysRole.getChannelIds() != null && !sysRole.getChannelIds().isEmpty()) {
                for (Long channelId : sysRole.getChannelIds()) {
                    SysRoleChannel sysRoleChannel = new SysRoleChannel();
                    sysRoleChannel.setRoleId(sysRole.getRoleId());
                    sysRoleChannel.setChannelId(channelId);
                    channelToSave.add(sysRoleChannel);
                }
                // 保存栏目
                if (!this.sysRoleChannelService.saveBatch(channelToSave)) {
                    return ResultVo.failure(ResultCode.FAILED);
                }
            }
            // 处理信息
            if (sysRole.getInfoIds() != null && !sysRole.getInfoIds().isEmpty()) {
                for (Long infoId : sysRole.getInfoIds()) {
                    SysRoleInfo sysRoleInfo = new SysRoleInfo();
                    sysRoleInfo.setRoleId(sysRole.getRoleId());
                    sysRoleInfo.setInfoId(infoId);
                    infoToSave.add(sysRoleInfo);
                }
                // 保存信息
                if (!this.sysRoleInfoService.saveBatch(infoToSave)) {
                    return ResultVo.failure(ResultCode.FAILED);
                }
            }
        }
        return ResultVo.success();
    }

    /**
     * 角色编辑
     *
     * @param sysRole 角色对象
     * @return 获取修改角色id, 返回更新后的角色
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo<SysRole> updateRole(@Validated SysRole sysRole) {
        if (!this.updateById(sysRole)) {
            return ResultVo.failure(ResultCode.FAILED);
        } else {
            List<Long> permissionIds = this.getPermissionIdsByRoleId(sysRole.getRoleId());
            List<Long> channelIds = this.getChannelIdsByRoleId(sysRole.getRoleId());
            List<Long> infoIds = this.getInfoIdsByRoleId(sysRole.getRoleId());
            if (!(sysRole.getInfoIds().equals(infoIds))) {
                QueryWrapper<SysRoleInfo> query = new QueryWrapper<>();
                query.lambda().eq(SysRoleInfo::getRoleId, sysRole.getRoleId());
                if (sysRole.getInfoIds().isEmpty()) {
                    this.sysRoleInfoService.remove(query);
                } else {
                    List<SysRoleInfo> infosToSave = new ArrayList<>();
                    this.sysRoleInfoService.remove(query);
                    for (Long infoId : sysRole.getInfoIds()) {
                        SysRoleInfo info = new SysRoleInfo();
                        info.setRoleId(sysRole.getRoleId());
                        info.setInfoId(infoId);
                        infosToSave.add(info);
                    }
                    if (!this.sysRoleInfoService.saveBatch(infosToSave)) {
                        return ResultVo.failure(ResultCode.FAILED);
                    }
                }

            }
            if (!(sysRole.getPermissionIds().equals(permissionIds))) {
                QueryWrapper<SysRolePermission> query = new QueryWrapper<>();
                query.lambda().eq(SysRolePermission::getRoleId, sysRole.getRoleId());
                if (sysRole.getPermissionIds().isEmpty()) {
                    this.sysRolePermissionService.remove(query);
                } else {
                    this.sysRolePermissionService.remove(query);
                    List<SysRolePermission> permissionsToSave = new ArrayList<>();
                    for (Long permissionId : sysRole.getPermissionIds()) {
                        SysRolePermission permission = new SysRolePermission();
                        permission.setRoleId(sysRole.getRoleId());
                        permission.setPermissionId(permissionId);
                        permissionsToSave.add(permission);
                    }
                    if (!this.sysRolePermissionService.saveBatch(permissionsToSave)) {
                        return ResultVo.failure(ResultCode.FAILED);
                    }
                }
            }
            if (!(sysRole.getChannelIds().equals(channelIds))) {
                QueryWrapper<SysRoleChannel> query = new QueryWrapper<>();
                query.lambda().eq(SysRoleChannel::getRoleId, sysRole.getRoleId());
                if (!(sysRole.getChannelIds()).isEmpty()) {
                    // 不为空，先删掉再重新插入
                    this.sysRoleChannelService.remove(query);
                    List<SysRoleChannel> channelsToSave = new ArrayList<>();
                    for (Long channelId : sysRole.getChannelIds()) {
                        SysRoleChannel channel = new SysRoleChannel();
                        channel.setRoleId(sysRole.getRoleId());
                        channel.setChannelId(channelId);
                        channelsToSave.add(channel);
                    }
                    if (!this.sysRoleChannelService.saveBatch(channelsToSave)) {
                        return ResultVo.failure(ResultCode.FAILED);
                    }
                } else {
                    this.sysRoleChannelService.remove(query);
                }
            }
            return ResultVo.success();
        }
    }

    /**
     * 根据角色Id获取权限Id
     *
     * @param roleId 角色Id
     * @return 角色对应的权限集合
     */
    @Override
    public List<Long> getPermissionIdsByRoleId(Long roleId) {
        return this.sysRolePermissionService.list(Wrappers.<SysRolePermission>lambdaQuery().eq(SysRolePermission::getRoleId, roleId))
                .stream()
                .map(SysRolePermission::getPermissionId)
                .collect(Collectors.toList());
    }

    /**
     * 根据角色Id获取栏目Id
     *
     * @param roleId 角色Id
     * @return 角色对应的栏目集合
     */
    @Override
    public List<Long> getChannelIdsByRoleId(Long roleId) {
        return this.sysRoleChannelService.list(Wrappers.<SysRoleChannel>lambdaQuery().eq(SysRoleChannel::getRoleId, roleId))
                .stream()
                .map(SysRoleChannel::getChannelId)
                .collect(Collectors.toList());
    }

    /**
     * 根据角色Id获取信息Id
     *
     * @return 角色对应的信息集合
     */
    @Override
    public List<Long> getInfoIdsByRoleId(Long roleId) {
        return this.sysRoleInfoService.list(Wrappers.<SysRoleInfo>lambdaQuery().eq(SysRoleInfo::getRoleId, roleId))
                .stream()
                .map(SysRoleInfo::getInfoId)
                .collect(Collectors.toList());
    }

    /**
     * 根据角色Id获取用户名
     *
     * @param roleId 角色Id
     * @return 获得的用户名列表
     */
    @Override
    public List<?> getUserIdByRoleId(Long roleId) {
        return this.sysRoleMapper.findUsernamesByRoleId(roleId);
    }

    @Override
    public ResultVo<?> getRoleList() {
        List<SysRole> list = this.list(new QueryWrapper<SysRole>().lambda().eq(SysRole::getType, 1));
        return ResultVo.success(list);
    }

    @Override
    public ResultVo<?> getDepartmentRoleList() {
        List<SysRole> list = this.list(new QueryWrapper<SysRole>().lambda().eq(SysRole::getType, 0));
        return ResultVo.success(list);
    }
}

